/* $Id: tabbed.jquery.js 29 2009-10-22 19:58:19Z geraldb $

Unobtrusive Accessible jQuery Tabs

Parameters:
	prefix: (String) String to prepend classes/id's
		Default: 'tab_'
	unifyHeight: (Bool) Resize content objects to be even
		Default: false
	tabchange: (Event) Event which fires when user changes tabs
		Default: null

Usage:
	JavaScript:
	$('selector').tabbed();

Author:
	gburns

TODO:
	documentation

*/

(function($) {
$.pluggie('tabbed', function() {
	var defaultSettings = {
		prefix: 'tab_',
		unifyHeight: false,
		tabchange: null
	};
	var settings = null;
	var $tabbed = null;
	var unify_height;
	var prefix;
	var tabchange;
	var container_class;
	var content_class;
	var title_class;
	var selected_class;

	var $tab_containers;
	var $tab_contents;
	var $tab_titles;
	var $selected_tab_container;
	var tabbed_padding_left;
	var tabbed_padding_top;
	var tabbed_border_left;
	var $selected_tab_content;

	var cur_title_width = 0;
	var max_title_height = 0;

	// Show/hide/add selected class to selected tab
	var update_visibility = function() {
		var $selected_tab_title = $('.' + title_class, $selected_tab_container);
		$selected_tab_content = $('.' + content_class, $selected_tab_container);

		$tab_containers.removeClass(selected_class);
		$selected_tab_container.addClass(selected_class);
	};

	this.unify_content_height = function() {
		var max_content_height = 0;
		$tab_contents
			.css({height: 'auto'})
			.each(function() {
				var $this = $(this);
				var height = $this.outerHeight();
				var margin_top = parseInt($this.css('marginTop')) || 0;
				var margin_bottom = parseInt($this.css('marginBottom')) || 0;
				var total_height = height + margin_top + margin_bottom;
				max_content_height = ( max_content_height < total_height ) ? total_height : max_content_height;
			})
			.each(function() {
				var $this = $(this);
				var outer_height = $this.outerHeight() + (parseInt($this.css('marginTop')) || 0) + (parseInt($this.css('marginBottom')) || 0);
				var inner_height = $this.innerHeight() - (parseInt($this.css('paddingTop')) || 0) - (parseInt($this.css('paddingBottom')) || 0);
				var extra_height = outer_height - inner_height;

				$this.css({height: max_content_height - extra_height});
			});
	};


	this._init = function(object, parameters) {
		$tabbed = object;
		settings = $.extend(defaultSettings, parameters || {});

		unify_height = settings.unifyHeight;
		prefix = settings.prefix;
		tabchange = settings.tabchange;
		container_class = prefix + 'container';
		content_class = prefix + 'content';
		title_class = prefix + 'title';
		selected_class = prefix + 'selected';

		$tab_containers = $('.' + container_class, $tabbed);
		$tab_contents = $('.' + content_class, $tabbed);
		$tab_titles = $('.' + title_class, $tabbed);

		
		$selected_tab_container = $tab_containers.filter('.' + selected_class);
		if ( $selected_tab_container.length ) {
			$selected_tab_container = $selected_tab_container.first();
		} else {
			$selected_tab_container = $tab_containers.first();
		}

		tabbed_padding_left = parseInt($tabbed.css('paddingLeft')) || 0;
		tabbed_padding_top = parseInt($tabbed.css('paddingTop')) || 0;
		tabbed_border_left = parseInt($tabbed.css('borderLeftWidth')) || 0;
		$selected_tab_content;

		$tabbed.css({position: 'relative'});
		$tabbed.addClass('tabbed');

		if ( tabchange ) $tabbed.bind('tabchange', tabchange);

		$tab_titles
			.css({position: 'absolute', top: tabbed_padding_top})
			.each(function() {
				var $this = $(this);
				var $a = $('<a href="javascript:;" />');
				$this.wrapInner($a);
				var height = $this.outerHeight();
				var margin_top = parseInt($this.css('marginTop')) || 0;
				var margin_bottom = parseInt($this.css('marginBottom')) || 0;
				var total_height = height + margin_top + margin_bottom;
				max_title_height = ( max_title_height < total_height ) ? total_height : max_title_height;

				$this.css({left: tabbed_padding_left + cur_title_width});
				cur_title_width += $this.outerWidth() + (parseInt($this.css('marginLeft')) || 0) + (parseInt($this.css('marginRight')) || 0);
			})
			.bind('click', function() {
				if ( $(this).is('.' + selected_class + ' .' + title_class) ) return false;

				$selected_tab_container = $tab_containers.has(this);
				update_visibility();
				$.event.trigger('tabchange', {object: object, container: $selected_tab_container}, $tabbed[0]);
			});

		update_visibility();

		$tabbed
			.css({paddingTop: tabbed_padding_top + max_title_height});

		if ( unify_height ) {
			this.unify_content_height();
			$(window)
				.bind('resize', this.unify_content_height);
		}
	};
});
})(jQuery);
